﻿using System;
using System.Collections.Generic;
using System.Linq;
using Monkey.Framework.Logging;
using Monkey.Warrenty.Data;
using Monkey.Warrenty.Data.Interfaces;
using Monkey.Warrenty.EntityModel;

namespace Monkey.Warrenty.Biz
{
    public class ProductBiz
    {
        #region Properties

        private readonly IProductGroupDao _productGroupDao;
        private readonly IProductDao _productDao;
        private readonly IManufacturerDao _manufacturerDao;
        private readonly IServiceTypeDao _serviceTypeDao;
        private readonly IErrorDao _errorDao;
        private readonly ISupplierDao _supplierDao;

        #endregion

        #region Constructors

        public ProductBiz()
        {
            _productDao = new ProductDao();
            _productGroupDao = new ProductGroupDao();
            _manufacturerDao = new ManufacturerDao();
            _serviceTypeDao = new ServiceTypeDao();
            _errorDao = new ErrorDao();
            _supplierDao = new SupplierDao();
        }

        public ProductBiz(IProductGroupDao productGroupDao, IProductDao productDao,
            IManufacturerDao manufacturerDao, IServiceTypeDao serviceTypeDao,
            IErrorDao errorDao, ISupplierDao supplierDao)
        {
            _productDao = productDao;
            _productGroupDao = productGroupDao;
            _manufacturerDao = manufacturerDao;
            _serviceTypeDao = serviceTypeDao;
            _errorDao = errorDao;
            _supplierDao = supplierDao;
        }

        #endregion

        #region ProductGroup Methods

        public List<ProductGroup> GetAllProductGroups()
        {
            try
            {
                return _productGroupDao.GetAllProductGroups();
            }
            catch (Exception ex)
            {
                LoggingFactory.GetLogger().Log(ex.ToString());
            }

            return new List<ProductGroup>();
        }

        public object GetProductGroupOptionsWs()
        {
            try
            {
                var groups = _productGroupDao.GetAllProductGroups();
                groups.Insert(0, new ProductGroup { Id = 0, Name = "" });
                return new { Result = "OK", Options = groups.Select(g => new { DisplayText = g.Name, Value = g.Id }) };
            }
            catch (Exception ex)
            {
                return new { Result = "ERROR", ex.Message };
            }
        }

        #endregion

        #region Manufacturer Methods

        public List<Manufacturer> GetAllManufacturers()
        {
            return _manufacturerDao.GetAllManufacturers();
        }

        public object GetManufacturerOptionsWs()
        {
            try
            {
                var groups = _manufacturerDao.GetAllManufacturers();
                groups.Insert(0, new Manufacturer { Id = 0, Name = "" });
                return new { Result = "OK", Options = groups.Select(g => new { DisplayText = g.Name, Value = g.Id }) };
            }
            catch (Exception ex)
            {
                return new { Result = "ERROR", ex.Message };
            }
        }

        #endregion

        #region ServiceType Methods

        public List<ServiceType> GetAllServiceTypes()
        {
            return _serviceTypeDao.GetAllServiceTypes();
        }

        #endregion

        #region Error Methods

        public List<Error> GetAllErrors()
        {
            return _errorDao.GetAllErrors();
        }

        #endregion

        #region Supplier Methods

        public List<Supplier> GetAllSuppliers()
        {
            return _supplierDao.GetAllSuppliers();
        }

        #endregion

        #region Product Methods

        public Product GetById(int id)
        {
            if (id <= 0) return null;
            try
            {
                return _productDao.GetById(id);
            }
            catch (Exception ex)
            {
                LoggingFactory.GetLogger().Log(ex.ToString());
            }

            return null;
        }

        public Product CreateProduct(Product product)
        {
            if (product == null) return null;
            if (string.IsNullOrEmpty(product.Code) || string.IsNullOrEmpty(product.Name)) return null;

            try
            {
                var addedProduct = _productDao.AddProduct(product);
                return addedProduct;
            }
            catch (Exception ex)
            {
                LoggingFactory.GetLogger().Log(ex.ToString());
                return null;
            }
        }

        public Product UpdateProduct(Product product)
        {
            if (product == null) return null;

            try
            {
                _productDao.UpdateProduct(product);
                return product;
            }
            catch (Exception ex)
            {
                LoggingFactory.GetLogger().Log(ex.ToString());
                return null;
            }
        }

        public int GetMaxId()
        {
            return _productDao.GetMaxId();
        }

        public int GetNextCode()
        {
            return _productDao.GetCurrentIdentity() + 1;
        }

        public object ProductListByFilterWs(string name, int productGroupId, int manufacturerId, int jtStartIndex, int jtPageSize, string jtSorting)
        {
            try
            {
                //Get data from database
                var productCount = _productDao.GetProductCountByFilter(name, productGroupId, manufacturerId);
                var products = _productDao.GetProductsByFilter(name, productGroupId, manufacturerId, jtStartIndex, jtPageSize, jtSorting);

                //Return result to jTable
                return new { Result = "OK", Records = products, TotalRecordCount = productCount };
            }
            catch (Exception ex)
            {
                return new { Result = "ERROR", ex.Message };
            }
        }

        public object CreateProductWs(Product product)
        {
            if (product == null) return null;
            if (string.IsNullOrEmpty(product.Code) || string.IsNullOrEmpty(product.Name)) return null;

            try
            {
                var addedProduct = _productDao.AddProduct(product);
                return new { Result = "OK", Record = addedProduct };
            }
            catch (Exception ex)
            {
                return new { Result = "ERROR", ex.Message };
            }
        }

        public object UpdateProductWs(Product product)
        {
            if (product == null) return null;

            try
            {
                _productDao.UpdateProduct(product);
                return new { Result = "OK" };
            }
            catch (Exception ex)
            {
                return new { Result = "ERROR", ex.Message };
            }
        }

        public object DeleteProductWs(int productId)
        {
            try
            {
                if (productId > 0)
                    _productDao.DeleteProduct(productId);
                return new { Result = "OK" };
            }
            catch (Exception ex)
            {
                return new { Result = "ERROR", ex.Message };
            }
        }

        #endregion
    }
}
